<template>
  <div
    class="video-play-back"
    :id="state.pid"
    :class="{ 'landscape-mode': props.isLandscape }"
  >
    <div v-if="noStream" class="no-stream-placeholder">
      <el-icon class="no-video-icon"><Plus /></el-icon>
      <p>暂无视频流信息</p>
    </div>
  </div>
</template>
<script setup>
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
import { playbackcameraurl } from "@/api/videoplan.js";
const emit = defineEmits(["capImg"]);
const props = defineProps({
  vid: String,
  Times: Array,
  url: "",
  currentIndexCode: String,
  capUrl: {
    type: Boolean,
    default: false,
  },
  startTime: {
    type: String,
  },
  endTime: {
    type: String,
  },
  storageType: {
    type: String,
    default: "1", //默认设备存储1，中心0
  },
  isLandscape: {
    type: Boolean,
    default: false,
  },
});
const state = reactive({
  pm: {},
  myPlugin: null,
  curIndex: 0,
  pid: "bk" + Math.floor(Math.random() * 1000) + 1,
  isRecording: false, // 记录是否正在录像
  isSoundOn: false, // 修正：默认静音（与父组件保持一致）
});
// 新增无流状态变量
const noStream = ref(false);

// 窗口大小调整
const resize = () => {
  if (state.myPlugin) {
    setTimeout(() => {
      state.myPlugin.JS_Resize();
    }, 50);
  }
};
// 播放回放
const playBack = async () => {
  try {
    let bt = dayjs(new Date(props.startTime))
      .subtract(10, "second")
      .format("YYYY-MM-DDTHH:mm:ss.SSSZ");
    let et = dayjs(new Date(props.endTime))
      .add(10, "second")
      .format("YYYY-MM-DDTHH:mm:ss.SSSZ");
    console.log("开始播放", bt, et);
    let pm = {
      cameraId: props.currentIndexCode,
      beginTime: props.startTime,
      endTime: props.endTime,
      uuid: "",
      ifwww: "1",
      recordLocation: props.storageType,
    };
    console.log("pm-----------", pm);
    let { data } = await playbackcameraurl({
      ...pm,
    });
    console.log("data", data.url);
    if (!data.url) {
      console.warn("未获取到视频流地址");
      noStream.value = true;
      emit("noVideoStream", true); // 通知父组件无流
      ElMessage.warning("当前无可用录像，相关操作暂不可用");
      return;
    }
    if (data.url) {
      noStream.value = false;
      emit("noVideoStream", false);

      state.myPlugin
        .JS_Play(data.url, { playURL: data.url, mode: 1 }, 0, bt, et)
        .then(
          () => console.log("播放成功"),
          (err) => {
            console.error("播放失败:", err);
            ElMessage.error(`播放失败: ${err.message}`);
          }
        );
    }
  } catch (e) {
    console.error(e);
  }
};

// 截图功能
const toCapImg = () => {
  if (!state.myPlugin) {
    console.error("播放器未初始化");
    ElMessage.error("播放器未初始化");
    return;
  }
  // 生成唯一文件名（时间戳+随机数）
  const fileName = `capture_${Date.now()}_${Math.floor(
    Math.random() * 1000
  )}.jpeg`;
  state.myPlugin
    .JS_CapturePicture(
      state.curIndex,
      fileName,
      "JPEG", // 修正：文件类型为JPEG（开发指南要求）
      (imageData) => {
        // 将 Base64 数据转换为 Blob 对象
        const byteCharacters = atob(imageData.split(",")[1]);
        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        const blob = new Blob([byteArray], { type: "image/jpeg" });
        // 保存文件到本地
        saveAsFile(blob, fileName);
        emit("capImg", imageData);
      }
    )
    .catch((err) => {
      console.error(`抓拍失败: ${err.message}`);
      ElMessage.error(`当前无可用录像，相关操作暂不可用`);
    });
};
// 保存文件到本地的函数
const saveAsFile = (blob, fileName) => {
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.style.display = "none";
  a.href = url;
  a.download = fileName;
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
  document.body.removeChild(a);
};

// 暂停功能
const pause = () => {
  return new Promise((resolve, reject) => {
    if (!state.myPlugin) {
      reject(new Error("播放器未初始化"));
      return;
    }
    // 调用H5Player的暂停接口，传入当前窗口索引state.curIndex
    state.myPlugin
      .JS_Pause(state.curIndex)
      .then(() => {
        console.log("暂停播放成功");
        resolve();
      })
      .catch((err) => {
        console.error("暂停播放失败:");
        ElMessage.error(`当前无可用录像，相关操作暂不可用`);
        reject(err);
      });
  });
};
// 恢复回放
const resume = () => {
  return new Promise((resolve, reject) => {
    if (!state.myPlugin) {
      reject(new Error("播放器未初始化"));
      return;
    }
    // 调用H5Player的恢复播放接口，传入当前窗口索引state.curIndex
    state.myPlugin
      .JS_Resume(state.curIndex)
      .then(() => {
        console.log("恢复播放成功");
        resolve();
      })
      .catch((err) => {
        console.error("恢复播放失败:", err);
        ElMessage.error(`恢复播放失败`);
        reject(err);
      });
  });
};
// 初始化播放器
const initPlayer = () => {
  if (state.myPlugin) return;
  try {
    state.myPlugin = new JSPlugin({
      szId: state.pid,
      szBasePath: "/js/", // 确保此路径指向H5Player.min.js所在目录
      bSupporDoubleClickFull: false,
      iMaxSplit: 1,
      iCurrentSplit: 1,
    });
    // 事件回调初始化
    state.myPlugin.JS_SetWindowControlCallback({
      windowEventSelect: (index) => {
        state.curIndex = index;
      },
      pluginErrorHandler: (iWndIndex, iErrorCode, oError) => {
        console.error(`窗口${iWndIndex}错误: ${iErrorCode}`, oError);
        ElMessage.error(`播放器错误: ${iErrorCode}`);
      },
      windowFullCcreenChange: (bFull) => {
        state.myPlugin.JS_Resize();
      },
    });
  } catch (err) {
    console.error("初始化播放器失败:", err);
    ElMessage.error("播放器加载失败，请检查插件路径");
  }
};

// 录像功能
const startRecording = () => {
  return new Promise((resolve, reject) => {
    if (!state.myPlugin) {
      reject(new Error("播放器未初始化"));
      return;
    }
    if (state.isRecording) {
      reject(new Error("正在录像中，请勿重复操作"));
      return;
    }
    // 生成唯一文件名（支持MP4格式）
    const fileName = `record_${dayjs().format("YYYYMMDDHHmmss")}`;
    // 调用插件录像接口（JS_StartSaveEx）
    state.myPlugin
      .JS_StartSaveEx(
        state.curIndex, // 窗口索引
        fileName, // 文件名
        5 // 5=MP4格式（开发指南定义）
      )
      .then(() => {
        state.isRecording = true;
        ElMessage.success("开始录像");
        resolve();
      })
      .catch((err) => {
        ElMessage.error(`当前无可用录像，相关操作暂不可用`);
        reject(err);
      });
  });
};

// 停止录像
const stopRecording = () => {
  return new Promise((resolve, reject) => {
    if (!state.myPlugin || !state.isRecording) {
      reject(new Error("未在录像中"));
      return;
    }
    state.myPlugin
      .JS_StopSave(state.curIndex)
      .then(() => {
        state.isRecording = false;
        ElMessage.success("录像已保存");
        resolve();
      })
      .catch((err) => {
        ElMessage.error(`停止录像失败: ${err.message}`);
        reject(err);
      });
  });
};

// 静音功能
const turnOffSound = () => {
  return new Promise((resolve, reject) => {
    if (!state.myPlugin) {
      reject(new Error("播放器未初始化"));
      return;
    }
    state.myPlugin
      .JS_CloseSound(state.curIndex)
      .then(() => {
        state.isSoundOn = false;
        ElMessage.success("已静音");
        resolve();
      })
      .catch((err) => {
        ElMessage.error(`静音失败: ${err.message}`);
        reject(err);
      });
  });
};

// 开启声音
const turnOnSound = () => {
  return new Promise((resolve, reject) => {
    if (!state.myPlugin) {
      reject(new Error("播放器未初始化"));
      return;
    }
    state.myPlugin
      .JS_OpenSound(state.curIndex)
      .then(() => {
        state.isSoundOn = true;
        ElMessage.success("已开启声音");
        resolve();
      })
      .catch((err) => {
        ElMessage.error(`当前无可用录像，相关操作暂不可用`);
        reject(err);
      });
  });
};
// 跳转到指定时间点播放
const playToOsdTime = (time) => {
  try {
    if (!time) return;
    let startTime = dayjs(time).format("YYYY-MM-DDTHH:mm:ss") + "Z";
    console.log("props.endTime------------)", props.endTime);
    let endTime = dayjs(props.endTime).format("YYYY-MM-DDTHH:mm:ss") + "Z";
    console.log("跳转到指定时间点播放startTime", startTime);
    console.log("endTime", endTime);
    state.myPlugin.JS_Seek(state.curIndex, startTime, endTime).then(
      () => {},
      (err) => {
        console.info("JS_Seek failed,失败", err);
      }
    );
  } catch (e) {
    console.error(e);
  }
};
// 快进指定秒数（15秒）
const seekForward = () => {
  if (!state.myPlugin) {
    reject(new Error("播放器未初始化"));
    return;
  }
  // 1. 获取当前播放时间（OSD时间，毫秒级，精度到秒）
  state.myPlugin.JS_GetOSDTime(state.curIndex).then((currentTimeMs) => {
    let startTime = dayjs(currentTimeMs)
      .add(20, "second")
      .format("YYYY-MM-DD HH:mm:ss");
    console.log("startTime", startTime);
    playToOsdTime(startTime);
  });
};

// 快退指定秒数（15秒）
const seekBackward = () => {
  if (!state.myPlugin) {
    reject(new Error("播放器未初始化"));
    return;
  }
  // 1. 获取当前播放时间
  state.myPlugin.JS_GetOSDTime(state.curIndex).then((currentTimeMs) => {
    let startTime = dayjs(currentTimeMs)
      .subtract(20, "second")
      .format("YYYY-MM-DD HH:mm:ss");
    console.log("快退按钮", startTime);
    playToOsdTime(startTime);
  });
};

// 重新加载视频流
const loadVideo = () => {
  // 实现视频加载逻辑（如初始化播放器、请求视频流等）
  console.log("重新加载视频流...");
  playBack(); // 重新取流
};

// 监听：时间、设备ID、存储方式变化时重新取流
watch(
  () => [
    props.startTime,
    props.endTime,
    props.currentIndexCode,
    props.storageType,
  ],
  (newVals) => {
    const [startTime, endTime, indexCode] = newVals;
    noStream.value = false; // 参数变化时先隐藏占位符
    if (startTime && endTime && indexCode && state.myPlugin) {
      console.log("重新取流");
      playBack(); // 重新取流
    }
  },
  { immediate: true, deep: true }
);

// 组件挂载时初始化
onMounted(initPlayer);

// 组件卸载时销毁播放器
onBeforeUnmount(() => {
  if (state.myPlugin) {
    state.myPlugin.JS_StopRealPlayAll();
    state.myPlugin.JS_DestroyWorker();
    state.myPlugin = null;
  }
});

// 暴露方法给父组件
defineExpose({
  startRecording,
  stopRecording,
  turnOnSound,
  turnOffSound,
  toCapImg,
  pause, //暂停
  resume, //恢复
  seekForward, //快进
  seekBackward,
  loadVideo, //重新加载视频流
  resize,
});
</script>
<style lang="scss" scoped>
.video-play-back {
  width: 100%;
  height: 100%;
}

.landscape-mode {
  position: fixed !important;
  z-index: 99999 !important;
  background: #1c1b1b !important;
  // 关键调整：先居中平移，再旋转，确保旋转后整体居中
  transform: translate(-50%, -50%) rotate(90deg);
  // 旋转后，宽度应等于视口高度，高度等于视口宽度（适配横屏）
  width: 100vh !important;
  height: 100vw !important;
  position: fixed !important; // 固定定位，脱离文档流，避免父容器限制
  top: 50% !important; // 垂直居中基准点
  left: 50% !important; // 水平居中基准点
  margin: 0 !important; // 清除可能的默认边距
  padding: 0 !important; // 清除内边距
  // 覆盖其他可能的限制样式
  max-width: none !important;
  max-height: none !important;
}
</style>
